package com.camerax.sample

import android.Manifest
import android.net.Uri
import android.provider.MediaStore
import android.view.View
import android.widget.Toast
import androidx.annotation.RequiresPermission
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageCaptureException
import androidx.core.os.bundleOf
import androidx.navigation.findNavController
import com.camerax.sample.base.BaseFragment
import com.camerax.sample.databinding.FragmentCameraxBinding
import com.google.android.material.shape.ShapeAppearanceModel
import java.util.concurrent.Executors

/**
 * date        ：2020/11/27
 * author      ：秦川小将
 * description ：
 */
class CameraXFragment: BaseFragment<FragmentCameraxBinding>(), View.OnClickListener {

    private var takePictureUri: Uri? = null

    private val executorService by lazy { Executors.newSingleThreadExecutor() }

    override fun layoutResId() = R.layout.fragment_camerax

    override fun initView() {
        binding.preview.shapeAppearanceModel = ShapeAppearanceModel.builder().setAllCornerSizes(ShapeAppearanceModel.PILL).build()
    }

    override fun loadData() {
        if (CameraCompat.checkSelfPermission(requireContext(), Manifest.permission.CAMERA)) {
            bindCameraUseCases()
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        executorService.shutdown()
        takePictureUri = null
    }

    override fun onBackPressed() {
        requireActivity().finish()
    }

    @RequiresPermission(Manifest.permission.CAMERA)
    private fun bindCameraUseCases() {
        binding.cameraView.bindToLifecycle(this)
    }

    override fun onClick(v: View?) {
        when(v?.id) {
            R.id.take_picture -> takePicture()
            R.id.camera_switch -> switchLensFacing()
            R.id.preview -> {
                if (takePictureUri != null) {
                    requireActivity().findNavController(R.id.host_fragment_container).navigate(R.id.to_preview_fragment, bundleOf(
                        CameraCompat.TAKE_PICTURE_RESULT to "$takePictureUri"
                    ))
                } else {
                    Toast.makeText(requireContext(), "请先拍照", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    /**
     * 切换镜头
     */
    private fun switchLensFacing() {
        binding.cameraView.toggleCamera()
        val isFacingBack = binding.cameraView.cameraLensFacing == CameraSelector.LENS_FACING_FRONT
        binding.cameraSwitch.animate().rotationY(if (isFacingBack) 180f else 0f).start()
    }

    /**
     * 拍照
     */
    private fun takePicture() {
        val fileOptions = ImageCapture.OutputFileOptions.Builder(requireContext().contentResolver, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, CameraCompat.getContentValues()).build()
        binding.cameraView.takePicture(fileOptions, executorService, object : ImageCapture.OnImageSavedCallback {
            override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
                requireActivity().runOnUiThread {
                    takePictureUri = outputFileResults.savedUri
                    binding.preview.setImageURI(outputFileResults.savedUri)
                    Toast.makeText(requireContext(), "Take Picture Uri：${outputFileResults.savedUri}", Toast.LENGTH_SHORT).show()
                }
            }

            override fun onError(exception: ImageCaptureException) {
                requireActivity().runOnUiThread {
                    Toast.makeText(requireContext(), "Take Picture Error：${exception.message}", Toast.LENGTH_SHORT).show()
                }
            }
        })
    }
}